package com.macro.mall.portal.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.macro.mall.common.exception.Assert;
import com.macro.mall.mgb.mapper.*;
import com.macro.mall.mgb.model.*;
import com.macro.mall.portal.dao.SmsCouponHistoryDao;
import com.macro.mall.portal.domain.CartPromotionItem;
import com.macro.mall.portal.domain.SmsCouponHistoryDetail;
import com.macro.mall.portal.service.MemberCouponService;
import com.macro.mall.portal.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author wangwang
 * @version 1.0
 * @description 会员优惠券管理
 * @date 2025/7/31 8:43
 */
@Service
public class MemberCouponServiceImpl implements MemberCouponService {
    @Autowired
    private SmsCouponMapper couponMapper;

    @Autowired
    private SmsCouponHistoryMapper couponHistoryMapper;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SmsCouponProductRelationMapper couponProductRelationMapper;

    @Autowired
    private SmsCouponProductCategoryRelationMapper smsCouponProductCategoryRelationMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private SmsCouponHistoryDao couponHistoryDao;

    @Override
    @Transactional
    public void add(Long couponId) {
        Member currentMember = memberService.getCurrentMember();
        SmsCoupon coupon = couponMapper.selectById(couponId);
        if (coupon == null) {
            Assert.fail("优惠券不存在");
        }
        if (coupon.getCount() <= 0) {
            Assert.fail("优惠券已经领完了");
        }
        Date now = new Date();
        if (now.before(coupon.getEnableTime())) {
            Assert.fail("优惠券还没到领取时间");
        }
        //查询领券记录，看是否超过数量限制
        LambdaQueryWrapper<SmsCouponHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SmsCouponHistory::getCouponId, couponId).eq(SmsCouponHistory::getMemberId, currentMember.getId());
        Long count = couponHistoryMapper.selectCount(wrapper);
        if (count >= coupon.getPerLimit()) {
            Assert.fail("您不能再领取该优惠券，超过了限制");
        }
        //生成领取优惠券历史
        SmsCouponHistory couponHistory = new SmsCouponHistory();
        couponHistory.setCouponId(couponId);
        couponHistory.setCouponCode(generateCouponCode(currentMember.getId()));
        couponHistory.setCreateTime(now);
        couponHistory.setMemberId(currentMember.getId());
        couponHistory.setMemberNickname(currentMember.getNickname());

        //主动领取
        couponHistory.setGetType(1);
        //未使用
        couponHistory.setUseStatus(0);
        couponHistoryMapper.insert(couponHistory);
        //修改优惠券表的数量、领取数量
        coupon.setCount(coupon.getCount() - 1);
        coupon.setReceiveCount(coupon.getReceiveCount() == null ? 1 : coupon.getReceiveCount() + 1);
        couponMapper.updateById(coupon);
    }

    @Override
    public List<SmsCoupon> listByProduct(Long productId) {
        // 1. 获取与商品关联的优惠券ID（指定商品）
        List<Long> allCouponIds = new ArrayList<>();

        // 1.1 查询指定商品的优惠券
        List<Long> productCouponIds = couponProductRelationMapper.selectList(
                        Wrappers.<SmsCouponProductRelation>lambdaQuery()
                                .eq(SmsCouponProductRelation::getProductId, productId))
                .stream()
                .map(SmsCouponProductRelation::getCouponId)
                .collect(Collectors.toList());
        allCouponIds.addAll(productCouponIds);

        // 1.2 查询商品分类的优惠券
        Product product = productMapper.selectById(productId);
        List<Long> categoryCouponIds = smsCouponProductCategoryRelationMapper.selectList(
                        Wrappers.<SmsCouponProductCategoryRelation>lambdaQuery()
                                .eq(SmsCouponProductCategoryRelation::getProductCategoryId, product.getProductCategoryId())
                ).stream()
                .map(SmsCouponProductCategoryRelation::getCouponId)
                .collect(Collectors.toList());
        allCouponIds.addAll(categoryCouponIds);

        // 2. 查询所有符合条件的优惠券
        LambdaQueryWrapper<SmsCoupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                // 基础条件：当前有效的优惠券（已开始且未过期）
                .gt(SmsCoupon::getEndTime, new Date())
                .lt(SmsCoupon::getStartTime, new Date())
                // 条件1：使用类型为0（如全场通用券）
                .eq(SmsCoupon::getUseType, 0);

        // 条件2：如果存在指定商品/分类的优惠券，额外查询这些券（使用类型≠0且ID在列表中）
        if (CollUtil.isNotEmpty(allCouponIds)) {
            queryWrapper.or(q -> q
                    .gt(SmsCoupon::getEndTime, new Date())
                    .lt(SmsCoupon::getStartTime, new Date())
                    .ne(SmsCoupon::getUseType, 0)
                    .in(SmsCoupon::getId, allCouponIds)
            );
        }
        return couponMapper.selectList(queryWrapper);
    }

    @Override
    public List<SmsCouponHistoryDetail> listCart(List<CartPromotionItem> cartItemList, Integer type) {
        Member member = memberService.getCurrentMember();
        List<SmsCouponHistoryDetail> detailList = couponHistoryDao.getDetailList(member.getId());
        List<SmsCouponHistoryDetail> enableCouponList = new ArrayList<>();
        List<SmsCouponHistoryDetail> disableCouponList = new ArrayList<>();
        Date now = new Date();
        for (SmsCouponHistoryDetail couponHistoryDetail : detailList) {
            //使用类型：0->全场通用；1->指定分类；2->指定商品
            Integer useType = couponHistoryDetail.getCoupon().getUseType();
            BigDecimal minPoint = couponHistoryDetail.getCoupon().getMinPoint();
            Date startTime = couponHistoryDetail.getCoupon().getStartTime();
            Date endTime = couponHistoryDetail.getCoupon().getEndTime();
            //0->全场通用
            if (useType == 0) {
                BigDecimal totalAmount = calcTotalAmount(cartItemList);
                ;
                if (now.after(startTime) && now.before(endTime) && totalAmount.subtract(minPoint).floatValue() >= 0) {
                    enableCouponList.add(couponHistoryDetail);
                } else {
                    disableCouponList.add(couponHistoryDetail);
                }
            } else if (useType == 1) {
                //1->指定分类
                List<Long> productCategoryIds = couponHistoryDetail.getCategoryRelationList().stream()
                        .map(SmsCouponProductCategoryRelation::getProductCategoryId).collect(Collectors.toList());
                BigDecimal totalAmount = calcTotalAmountByproductCategoryId(cartItemList, productCategoryIds);
                if (now.after(startTime) && now.before(endTime) && totalAmount.subtract(minPoint).floatValue() >= 0) {
                    enableCouponList.add(couponHistoryDetail);
                } else {
                    disableCouponList.add(couponHistoryDetail);
                }
            } else if (useType == 2) {
                //2->指定商品
                List<Long> productIds = new ArrayList<>();
                for (SmsCouponProductRelation productRelation : couponHistoryDetail.getProductRelationList()) {
                    productIds.add(productRelation.getProductId());
                }
                BigDecimal totalAmount = calcTotalAmountByProductId(cartItemList, productIds);
                if (now.before(endTime) && totalAmount.floatValue() > 0 && totalAmount.subtract(minPoint).floatValue() >= 0) {
                    enableCouponList.add(couponHistoryDetail);
                } else {
                    disableCouponList.add(couponHistoryDetail);
                }
            }
        }
        return type.equals(1) ? enableCouponList : disableCouponList;
    }

    private BigDecimal calcTotalAmountByProductId(List<CartPromotionItem> cartItemList, List<Long> productIds) {
        BigDecimal total = new BigDecimal("0");
        for (CartPromotionItem item : cartItemList) {
            if (productIds.contains(item.getProductId())) {
                BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
                total = total.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
            }
        }
        return total;
    }


    private BigDecimal calcTotalAmountByproductCategoryId(List<CartPromotionItem> cartItemList, List<Long> productCategoryIds) {
        BigDecimal amount = new BigDecimal(0);
        for (CartPromotionItem item : cartItemList) {
            if (productCategoryIds.contains(item.getProductCategoryId())) {
                BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
                amount = amount.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
            }
        }
        return amount;
    }


    private BigDecimal calcTotalAmount(List<CartPromotionItem> cartItemList) {
        BigDecimal amount = new BigDecimal(0);
        for (CartPromotionItem item : cartItemList) {
            BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
            amount = amount.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
        }
        return amount;
    }

    @Override
    public List<SmsCoupon> list(Integer useStatus) {
        Member member = memberService.getCurrentMember();
        return couponHistoryDao.getCouponList(member.getId(), useStatus);
    }

    //生成优惠券id -> 16位优惠码生成：时间戳后8位+4位随机数+用户id后4位
    private String generateCouponCode(Long id) {
        String time = String.valueOf(System.currentTimeMillis());
        String substring = time.substring(time.length() - 8);
        StringBuilder builder = new StringBuilder();
        builder.append(substring);
        Random random = new Random();
        for (int i = 0; i < 4; i++) {
            builder.append(random.nextInt(10));
        }
        String memberId = id.toString();
        if (memberId.length() <= 4) {
            builder.append(String.format("%04d", id));
        } else {
            builder.append(memberId.substring(memberId.length() - 4));
        }
        return builder.toString();
    }

}
